/*
 * Copyright 2016-2016 the original author or authors.
 * Created on 2016/12/22 下午8:48
 */
package cn.com.geasy.config;

import cn.com.geasy.base.repoisitory.BaseRepositoryFactoryBean;
import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.JpaVendorAdapter;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.Database;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
import java.sql.SQLException;

/**
 * 数据库相关配置
 *
 * @author Mechanic
 * @version 1.0
 */
@Configuration
@EnableJpaRepositories(
  basePackages = {"cn.com.geasy.dao", "cn.com.geasy.base.Repoisitory"},
  repositoryFactoryBeanClass = BaseRepositoryFactoryBean.class)
public class DataConfig {
    /**
     * 驱动
     */
    private final static String DRIVER_CLASS_NAME = "com.mysql.jdbc.Driver";
    /**
     * 连接地址
     */
    private final static String URL = "jdbc:mysql://localhost:3306/geasy"
                                      + "?useUnicode=true"
                                      + "&characterEncoding=utf8"
                                      + "&zeroDateTimeBehavior=convertToNull"
                                      + "&allowMultiQueries=true"
                                      + "&serverTimezone=PRC"
                                      + "&useSSL=false";
    /**
     * 用户名
     */
    private final static String USERNAME = "root";
    /**
     * 密码
     */
    private final static String PASSWORD = "123456";
    /**
     * 池里不会被释放的最多空闲连接数。如果设置为0，表示无限制
     */
    private final static int MAX_IDEL = 10;
    /**
     * 池启动时创建的连接数量
     */
    private final static int INITIAL_SIZE = 5;
    /**
     * 同一时间可从池中分配的最多连接数。如果设置为0，表示无限制
     */
    private final static int MAX_ACTIVE = 20;
    /**
     * 在同一时间能够从语句池中分配的预处理语句（prepared statement）的最大数量。如果设置为0，表示无限制
     */
    private final static int MAX_OPEN_PERPARED_STATEMENTS = 0;

    /**
     * 数据源连接池
     *
     * @return 数据源连接池
     */
    @Bean
    public DataSource dataSource() {
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setDriverClassName(DRIVER_CLASS_NAME);
        dataSource.setUrl(URL);
        dataSource.setUsername(USERNAME);
        dataSource.setPassword(PASSWORD);
        dataSource.setInitialSize(INITIAL_SIZE);
        dataSource.setMinIdle(1);
        dataSource.setMaxActive(MAX_ACTIVE);
        dataSource.setMaxWait(60000);
        dataSource.setTimeBetweenEvictionRunsMillis(60000);
        dataSource.setMinEvictableIdleTimeMillis(300000);
        dataSource.setValidationQuery("SELECT 'x'");
        dataSource.setTestWhileIdle(true);
        dataSource.setTestOnBorrow(false);
        dataSource.setTestOnReturn(false);

        // Oralce 设为 true，MySQL 设为 false
        dataSource.setPoolPreparedStatements(false);
        dataSource.setMaxPoolPreparedStatementPerConnectionSize(20);
        try {
            dataSource.setFilters("stat");
        } catch (SQLException e) {
            e.printStackTrace();
        }

        //BasicDataSource dataSource = new BasicDataSource();
        //dataSource.setDriverClassName(DRIVER_CLASS_NAME);
        //dataSource.setUrl(URL);
        //dataSource.setUsername(USERNAME);
        //dataSource.setPassword(PASSWORD);
        //dataSource.setMaxIdle(MAX_IDEL);
        //dataSource.setInitialSize(INITIAL_SIZE);
        return dataSource;
    }

    @Bean
    public JpaVendorAdapter jpaVendorAdapter() {
        HibernateJpaVendorAdapter jpaVendorAdapter = new HibernateJpaVendorAdapter();
        jpaVendorAdapter.setDatabase(Database.MYSQL);
        jpaVendorAdapter.setShowSql(true);
        jpaVendorAdapter.setGenerateDdl(false);
        jpaVendorAdapter.setDatabasePlatform("org.hibernate.dialect.HSQLDialect");
        return jpaVendorAdapter;
    }

    @Bean
    public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
        LocalContainerEntityManagerFactoryBean emf = new LocalContainerEntityManagerFactoryBean();
        emf.setDataSource(this.dataSource());
        emf.setJpaVendorAdapter(this.jpaVendorAdapter());
        emf.setPackagesToScan("cn.com.geasy.entity");
        return emf;
    }

    @Configuration
    @EnableTransactionManagement
    public static class TransactionConfig {

        private final EntityManagerFactory emf;

        @Autowired
        public TransactionConfig(EntityManagerFactory emf) {this.emf = emf;}

        @Bean
        public PlatformTransactionManager transactionManager() {
            JpaTransactionManager transactionManager = new JpaTransactionManager();
            transactionManager.setEntityManagerFactory(emf);
            return transactionManager;
        }
    }
}
